import logging

import psycopg2
from psycopg2.extras import DictCursor


def select(sql) -> list | None:
    """
    Формирование списка из словарей
            вида ключ:значение, где ключ берется из название столбца в запросе
    Args:
            sql (str): sql для выборки
    Returns:
            list: dicts in list
            OR
            None if len(result is 0)
    """
    try:
        conn = psycopg2.connect(
            host="192.168.100.10",
            dbname="med",
            user="SOLUTION_MED",
            password="elsoft",
        )
        result = []
        with conn.cursor(cursor_factory=DictCursor) as cur:
            cur.execute(sql)
            if cur.rowcount > 0:
                res = cur.fetchall()
                for row in res:
                    result.append(dict(row))
    except Exception:
        logging.exception("error select from database")
        if conn:
            conn.rollback()
            print("Отмена изменений в базе данных")
    finally:
        if conn:
            conn.close()
            print("Соединение с PostgreSQL закрыто")
        if len(result) == 0:
            return None
        return result


def write(sql):
    """Запись данных в бд firebird

    Args:
        sql (str): sql запрос для записи данных в бд
    """
    try:
        conn = psycopg2.connect(
            host="192.168.100.10",
            dbname="med",
            user="SOLUTION_MED",
            password="elsoft",
        )
        with conn.cursor() as cur:
            cur.execute(sql)
    except Exception:
        logging.exception("Error write to database")
        if conn:
            conn.rollback()
        print("Отмена изменений в базе данных")
    finally:
        if conn:
            conn.commit()
            conn.close()
            print("Соединение с PostgreSQL закрыто")


def write_many(sql, var_list):
    """Запись данных в бд firebird

    Args:
        sql (str): sql запрос для записи данных в бд
    """
    # >>> nums = ((1,), (5,), (10,))
    # >>> cur.executemany("INSERT INTO test (num) VALUES (%s)", nums)

    # >>> tuples = ((123, "foo"), (42, "bar"), (23, "baz"))
    # >>> cur.executemany("INSERT INTO test (num, data) VALUES (%s, %s)", tuples)
    try:
        conn = psycopg2.connect(
            host="192.168.100.10",
            dbname="med",
            user="SOLUTION_MED",
            password="elsoft",
        )
        with conn.cursor() as cur:
            cur.executemany(sql, var_list)

    except psycopg2.Error:
        logging.exception("Error write to database")
        if conn:
            conn.rollback()
            print("Отмена изменений в базе данных")
    finally:
        if conn:
            conn.commit()
            conn.close()
        print("Соединение с PostgreSQL закрыто")


def proc(proc_name, params=None):
    try:
        conn = psycopg2.connect(
            host="192.168.100.10",
            dbname="med",
            user="SOLUTION_MED",
            password="elsoft",
        )
        with conn.cursor() as cur:
            if params is None:
                cur.callproc(proc_name)
            if len(params) > 0:
                cur.callproc(proc_name, params)
    except Exception:
        logging.exception("Error exec procedure")
    finally:
        if conn:
            conn.commit()
            conn.close()


# fetchone(), fetchmany(number), conn.commit(), conn.rollback()
